package gtpcommand

import (
	"bufio"
	"fmt"
	"io"
	"os/exec"
	"strings"
)

type CMDClient struct {
	cmd     *exec.Cmd
	inPut   io.WriteCloser
	outPut  io.ReadCloser
	errPut  io.ReadCloser
	command CommandInterface
	azWait  chan int
	isClose bool
}

// NewGTPConnection 创建GTP连接器
func NewCMDClient(cmd string, args ...string) (*CMDClient, error) {
	conn := CMDClient{}
	conn.cmd = exec.Command(cmd, args...)
	inf, err := conn.cmd.StdinPipe() //获取输入管道，后续通过管道与AI进行交互
	if err != nil {
		return nil, err
	}
	conn.inPut = inf
	outInput, err := conn.cmd.StdoutPipe() //获取输入管道，在输入管道有命令进入时，通过输出管道获取命令返回值
	if err != nil {
		return nil, err
	}
	conn.outPut = outInput
	errInput, err := conn.cmd.StderrPipe() //获取输入管道，在输入管道有命令进入时，通过输出管道获取命令返回值
	if err != nil {
		return nil, err
	}
	conn.errPut = errInput
	if err = conn.cmd.Start(); err != nil {
		return nil, err
	} //开始命令，
	go func() {
		err = conn.cmd.Wait()
		if err!=nil{
			conn.command.StdOut(fmt.Sprintf("? %s", err.Error()))
			conn.Close()
		}
	}()
	return &conn, nil
}

// 完整PATH,自动解析为对应命令行
func NewCMDClientString(path string) (*CMDClient, error) {
	s1 := strings.Fields(path)
	command := s1[0]
	return NewCMDClient(command, s1[1:]...)
}
func (g *CMDClient) Build(command CommandInterface) {
	g.command = command
	go g.ListenErr()
	go g.ListenOut()
}
func (g *CMDClient) PostCommand(cmd string, ops ...bool) error {
	_, err := g.inPut.Write([]byte(fmt.Sprintf("%s\n", cmd)))
	return err
}

// Exec 通过管道执行命令并得到返回值
func (g *CMDClient) ListenOut() {
	reader := bufio.NewReader(g.outPut)
	for {
		line, err := reader.ReadString('\n')
		if err != nil || io.EOF == err {
			break
		}
		g.command.StdOut(line)
	}
}
func (g *CMDClient) ListenErr() {
	reader := bufio.NewReader(g.errPut)
	for {
		line, err := reader.ReadString('\n')
		if err != nil || io.EOF == err {
			return
		}
		g.command.StdErr(line)
	}
}

// Close 释放GTP资源
func (g CMDClient) Close() {
	if !g.isClose {
		g.isClose = true
		_ = g.PostCommand("quit")
		_ = g.inPut.Close()
		_ = g.outPut.Close()
		_ = g.errPut.Close()
	}
}
